package com.NeuglsWorkStudio.UI
{
	import com.NeuglsWorkStudio.Colors.RGB;
	import com.NeuglsWorkStudio.UI.Buttons.TTipButton;
	import com.NeuglsWorkStudio.UI.FormElement.Component.TBitButton;
	import com.NeuglsWorkStudio.UI.FormElement.Component.TBorderButton;
	import com.NeuglsWorkStudio.UI.FormElement.Component.TButton;
	import com.NeuglsWorkStudio.UI.FormElement.Component.TCheckBox;
	import com.NeuglsWorkStudio.UI.FormElement.Component.TComponent;
	import com.NeuglsWorkStudio.UI.FormElement.Component.TEdit;
	import com.NeuglsWorkStudio.UI.FormElement.Component.TImage;
	import com.NeuglsWorkStudio.UI.FormElement.Component.TLabel;
	import com.NeuglsWorkStudio.UI.FormElement.Component.TLine;
	import com.NeuglsWorkStudio.UI.FormElement.Component.TLinkLabel;
	import com.NeuglsWorkStudio.UI.FormElement.Component.TListBox;
	import com.NeuglsWorkStudio.UI.FormElement.Component.TMemo;
	import com.NeuglsWorkStudio.UI.FormElement.Component.TPanel;
	import com.NeuglsWorkStudio.UI.FormElement.Component.TProgressBar;
	import com.NeuglsWorkStudio.UI.FormElement.Component.TRadioBox;
	import com.NeuglsWorkStudio.UI.FormElement.Component.TRadioGroup;
	import com.NeuglsWorkStudio.UI.FormElement.Component.TTitleBar;
	import com.NeuglsWorkStudio.UI.FormElement.Config.TConfig;
	import com.NeuglsWorkStudio.UI.FormElement.Config.TTitleBarConfig;
	
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.filters.DropShadowFilter;
	import flash.ui.Mouse;
	import flash.ui.MouseCursor;
	
	/**
	 * This class implemets a form with client area, title bar and icon
	 * @author Neugls
	 * */
	public class TForm extends Sprite
	{
		public static const ctButton:int=0;
		public static const ctBitButton:int=1;
		public static const ctLable:int=2;
		public static const ctLinkLable:int=3;
		public static const ctEdit:int=4;
		public static const ctMemo:int=5;
		public static const ctImage:int=6;
		public static const ctLine:int=7;
		public static const ctCheckBox:int=8;
		public static const ctProgressBar:int=9;
		public static const ctRadioBox:int=10;
		public static const ctRadioGroup:int=11;
		public static const ctBorderButton:int=12;
		public static const ctListBox:int=13;
		public static const ctPanel:int=14;
		
		private var _FCaption:String="Form";
		private var _FWidth:Number=400;
		private var _FHeight:Number=300;
		private var _FBaseColor:int=0xFFFFFF;
		
		private var _FComponents:Vector.<TComponent>;
		private var _FClientArea:Sprite;
		private var _FTitle:TTitleBar;
		private var _FIcon:flash.display.DisplayObject=null;
		private var _FCloseBtnTip:String="Click here to close this form";
		private var _FIsDraging:Boolean=false;

		public function get Icon():flash.display.DisplayObject
		{
			return _FIcon;
		}

		public function set Icon(value:flash.display.DisplayObject):void
		{
			_FIcon = value;
			_FTitle.Icon=value;
		}

		public function get CloseBtnTip():String
		{
			return _FCloseBtnTip;
		}

		public function set CloseBtnTip(value:String):void
		{
			_FCloseBtnTip = value;
			_FTitle.CloseBtnTip=value;
		}

		/**The base color of the form. All the objects' color would changed occording to the
		 * base color*/
		public function get BaseColor():int
		{
			return _FBaseColor;
		}

		/**
		 * @private
		 */
		public function set BaseColor(value:int):void
		{
			_FBaseColor = value;
		}

		/**Occurs when the form to be showed*/
		public function get OnShow():Function
		{
			return _FOnShow;
		}

		/**
		 * @private
		 */
		public function set OnShow(value:Function):void
		{
			_FOnShow = value;
		}

		private var _FOnClose:Function;
		private var _FOnShow:Function;

		/**Occurs when this form to be closed*/
		public function get OnClose():Function
		{
			return _FOnClose;
		}

		/**
		 * @private
		 */
		public function set OnClose(value:Function):void
		{
			_FOnClose = value;
		}

		
		public function TForm(ABaseColor:int)
		{
			super();
			
			_FBaseColor=ABaseColor;
			Init();
		}

		/**Height of the form**/
		public function get Height():Number
		{
			return _FHeight;
		}

		/**
		 * @private
		 */
		public function set Height(value:Number):void
		{
			_FHeight = value;
		}

		/**Width of the form**/
		public function get Width():Number
		{
			return _FWidth;
		}

		/**
		 * @private
		 */
		public function set Width(value:Number):void
		{
			_FWidth = value;
		}

		/**
		 * Title of the form
		 * */
		public function get Caption():String
		{
			return _FCaption;
		}

		/**
		 * @private
		 */
		public function set Caption(value:String):void
		{
			_FCaption = value;
			_FTitle.Caption=value;
		}

		
		//*******************************************************
		/**
		 * Add a compoent to the form.
		 * @param ComponentType Which kind of component your want to add to the form,
		 * it value can defines at this class as static public const, like ctButton etc..
		 * @param ComponentConfig The config information of the component, it may be a kind 
		 * defined in FormElement/Config package. Such as, if you want to add a label
		 * to the form, the compoent type param may be ctLabel, the Component Config 
		 * param may be LabelConfig
		 * **/
		public function AddComponent(ComponentType:int,ComponentConfig:TConfig):void{
			var component:TComponent;
			switch(ComponentType){
				case ctButton:
					component=new TButton(ComponentConfig);
					break;
				case ctBitButton:
					component=new TBitButton(ComponentConfig);
					break;
				case ctLable:
					component=new TLabel(ComponentConfig);
					break;
				case ctLinkLable:
					component=new TLinkLabel(ComponentConfig);
					break;
				case ctEdit:
					component=new TEdit(ComponentConfig);
					break;
				case ctMemo:
					component=new TMemo(ComponentConfig);
					break;
				case ctImage:
					component=new TImage(ComponentConfig);
					break;
				case ctLine:
					component=new TLine(ComponentConfig);
					break;
				case ctCheckBox:
					component=new TCheckBox(ComponentConfig);
					break;
				case ctProgressBar:
					component=new TProgressBar(ComponentConfig);
					break;
				case ctRadioBox:
					component=new TRadioBox(ComponentConfig);
					break;
				case ctRadioGroup:
					component=new TRadioGroup(ComponentConfig);
					break;
				case ctBorderButton:
					component=new TBorderButton(ComponentConfig);
					break;
				case ctListBox:
					component=new TListBox(ComponentConfig);
					break;
				case ctPanel:
					component=new TPanel(ComponentConfig);
					break;
				default:
					throw new Error("Error component type: "+ComponentType);
			}
			
			_FComponents.push(component);
			_FClientArea.addChild(component);
			
		}
		
		public function AddComponents(Components:Array):void{
			if(Components==null){
				return;
			}
			for(var i:int=0;i<Components.length;i++){
				AddComponent(Components[i].ComponentType,Components[i].ComponentConfig);
			}
		}
		
		public function GetComponentByName(AName:String):TComponent{
			return _FClientArea.getChildByName(AName) as TComponent;
		}
		
		private function GetTitleConfig():TTitleBarConfig{
			var titleConfig:TTitleBarConfig=new TTitleBarConfig();
			titleConfig.BaseColor=_FBaseColor;
			titleConfig.Caption=_FCaption;
			titleConfig.CloseBtnTip=_FCloseBtnTip;
			titleConfig.OnClose=function():void{
				if(_FOnClose!=null){
					_FOnClose();
				}
			};
			titleConfig.Height=40;
			titleConfig.Width=_FWidth;
			titleConfig.Name="title";
			titleConfig.Icon=_FIcon;
			titleConfig.x=0;
			titleConfig.y=0;
			
			return titleConfig;
		}
		private function Init():void{
			_FComponents=new Vector.<TComponent>();
			_FClientArea=new Sprite();
			
			
			_FTitle=new TTitleBar(GetTitleConfig());
			
			
			this.addChild(_FTitle);
			this.addChild(_FClientArea);
			_FTitle.addEventListener(MouseEvent.MOUSE_DOWN,HandleTitleMouseEvent,false,0,true);
			_FTitle.addEventListener(MouseEvent.MOUSE_UP,HandleTitleMouseEvent,false,0,true);
			_FTitle.addEventListener(MouseEvent.MOUSE_MOVE,HandleTitleMouseEvent,false,0,true);
			
			Paint();
			
		}
		
		protected function Paint():void{
			with(_FTitle){
				x=0;
				y=0;
			}
			with(_FClientArea.graphics){
				clear();
				beginFill(_FBaseColor,1);
				drawRect(0,0,_FWidth,_FHeight-_FTitle.height);
				endFill();
			}
			_FClientArea.x=0;
			_FClientArea.y=_FTitle.y+_FTitle.height-1;
			
			for(var i:int=0;i<_FComponents.length;i++){
				_FClientArea.addChild(_FComponents[i]);
			}
			
			this.filters=[new DropShadowFilter(0,0,0x222222,0.9,30,30)];
		}
		
		public function Resize(w:Number=0,h:Number=0):void{
			if(!(w==0&&h==0)){
				_FWidth=w;
				_FHeight=h;
			}
			_FTitle.Resize(_FWidth,40);
			
			Paint();
		}
		
		private function HandleTitleMouseEvent(e:MouseEvent):void{
			switch(e.type){
				case MouseEvent.MOUSE_DOWN:
					_FIsDraging=true;
					this.startDrag(false,null);
					Mouse.cursor=MouseCursor.HAND;
					break;
				case MouseEvent.MOUSE_MOVE:
					break;
				case MouseEvent.MOUSE_UP:
					this.stopDrag();
					Mouse.cursor=MouseCursor.AUTO;
					_FIsDraging=false;
					break;
			}
		}
		
		public function get ClientHeight():Number{
			return this.Height-_FTitle.Height;
		}
	}
}